package display.tabs;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import display.threads.MyThread;

public class ThreadMonitor extends Tab{

	private static HashMap<String,MyThread> children = new HashMap<String,MyThread>();
	private static boolean newKids = true;
	private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	private HelperThread ht = new HelperThread(); 
	private JTable table = new JTable();
	private JScrollPane scrollPane = new JScrollPane(table);
	private final JButton btnNewButton = new JButton("Test");
	
	public ThreadMonitor() {
		super(null);
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{220, 0};
		gridBagLayout.rowHeights = new int[]{10, 0, 0};
		gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{1.0, 1.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
		JPanel panel = new JPanel();
		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.insets = new Insets(0, 0, 5, 0);
		gbc_panel.fill = GridBagConstraints.HORIZONTAL;
		gbc_panel.anchor = GridBagConstraints.NORTH;
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 0;
		add(panel, gbc_panel);
		
		panel.add(btnNewButton);
		btnNewButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				newKids = true;
			}
			
		});
		
		initTable();
		
		GridBagConstraints gbc_scrollPane = new GridBagConstraints();
		gbc_scrollPane.fill = GridBagConstraints.BOTH;
		gbc_scrollPane.gridx = 0;
		gbc_scrollPane.gridy = 1;
		add(scrollPane, gbc_scrollPane);
		
		start(new HelperThread());
	}
	
	public static void start(MyThread thread) {
		lock.writeLock().lock();
		children.put(thread.getName(), thread);
		newKids = true;
		lock.writeLock().unlock();
		thread.setStatus("started");
		((Thread)thread).start();
	}
	
	public static void stop(MyThread thread) {
		lock.writeLock().lock();
		children.remove(thread.getName());
		newKids = true;
		thread.setLoop(false);
		lock.writeLock().unlock();
		thread.setStatus("stopping");
	}
	
	private void initTable() {
		
		table.setModel(new DefaultTableModel(
			new Object[][] {
				{"Monitor", "updating"},
			},
			new String[] {
				"Thread", "Status"
			}
		) {
			Class[] columnTypes = new Class[] {
				String.class, String.class
			};
			@Override
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}
		});
	}
	
	private class HelperThread extends MyThread {
		
		private int myRow = -1;
		
		HelperThread() {
			super(null, "Monitor", true);
		}
		
		private void initTable() {
			myRow = -1;
			ThreadMonitor.this.initTable();
		}

		@Override
		public void myRun() {
			// TODO Auto-generated method stub
			if (newKids) {
				setStatus("updating");
				initTable();
				
				lock.readLock().lock();
				DefaultTableModel dtm = (DefaultTableModel) table.getModel();
				
				int count = 0;
				
				for (MyThread t : children.values()) {
					if (t != this)
						dtm.addRow(new String[] {t.getName(), t.getStatus()});
				}
				newKids = false;
				
				setStatus("running");
				
				lock.readLock().unlock();
			}
		}
		
		@Override
		public void setStatus(String stat) {
			super.setStatus(stat);
			if (myRow < 0)
				return;
			DefaultTableModel dtm = (DefaultTableModel) table.getModel();
			dtm.setValueAt(stat, myRow, 1);
		}
	}
}
